#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#include<time.h>
#include<ctype.h>
#include <time.h>
#include <windows.h>
#include <process.h>
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
int ChieuDai;
int xoay_0;
int Dai;
void VaoGame();
void DiChuyen();
void ConMoi();
void KhoiTao();
void gotoxy(int x, int y);
void Xoay();
void TaoMap();
void Down();
void Left();
void Up();
void Right();
void Delay(int k);
void ExitGame();
typedef struct snake
{
    int x;
    int y;
    int DieuHuong;
}snake;
snake Ran,xoay[500],conmoi,Than[30];
int main()
{
    KhoiTao();
    system("cls");
    VaoGame();
    ChieuDai=5;
    Ran.x=25;
    Ran.y=20;
    Ran.DieuHuong=RIGHT;
    TaoMap();
    ConMoi();   
    xoay[0]=Ran;
    DiChuyen();   
    return 0;
}
void DiChuyen()
{
    int a,i;
    do
    {
        ConMoi();
        fflush(stdin);
        Dai=0;
        for(i=0; i<30; i++)
        {
            Than[i].x=0;
            Than[i].y=0;
            if(i==ChieuDai)
                break;
        }
        Delay(ChieuDai); 
        TaoMap();
        if(Ran.DieuHuong==RIGHT)
            Right();
        else if(Ran.DieuHuong==LEFT)
            Left();
        else if(Ran.DieuHuong==DOWN)
            Down();
        else if(Ran.DieuHuong==UP)
            Up();
        ExitGame();
    }
    while(!kbhit());
    a=getch();
    if(a==27)
    {
        system("cls");
        exit(0);
    }
    char key=getch();
    if((key==RIGHT&&Ran.DieuHuong!=LEFT&&Ran.DieuHuong!=RIGHT)||(key==LEFT&&Ran.DieuHuong!=RIGHT&&Ran.DieuHuong!=LEFT)||(key==UP&&Ran.DieuHuong!=DOWN&&Ran.DieuHuong!=UP)||(key==DOWN&&Ran.DieuHuong!=UP&&Ran.DieuHuong!=DOWN))
    {
        xoay_0++;
        xoay[xoay_0]=Ran;
        Ran.DieuHuong=key;
        if(key==UP)
            Ran.y--;
        if(key==DOWN)
            Ran.y++;
        if(key==RIGHT)
            Ran.x++;
        if(key==LEFT)
            Ran.x--;
        DiChuyen();
    }
    else if(key==27)
    {
        system("cls");
        exit(0);
    }
    else
    {
        printf("\a");
        DiChuyen();
    }
}
void gotoxy(int x, int y)
{
    COORD coord;  
    coord.X = x;
    coord.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void VaoGame()
{
    int i,j;
    gotoxy(36,14);
    printf("loading...");
    gotoxy(30,15);
    for(i=1; i<=20; i++)
    {
        for(j=0; j<=10000000; j++); 
        printf("%c",176);
    }
    getch();
}
void Down()
{
    for(int i=0; i<=(Ran.y-xoay[xoay_0].y)&&Dai<ChieuDai; i++)
    {
        gotoxy(Ran.x,Ran.y-i);
        {
            if(Dai==0)
                printf("%c",2);
            else
                printf("%c",5);
        }
        Than[Dai].x=Ran.x;
        Than[Dai].y=Ran.y-i;
        Dai++;
    }
    Xoay();
    if(!kbhit())
        Ran.y++;
}   
void ExitGame()
{
    int i,check=0;
    for(i=4; i<ChieuDai; i++)
    {
        if(Than[0].x==Than[i].x&&Than[0].y==Than[i].y)
        {
            check++;    
        }
        if(i==ChieuDai||check!=0)
            break;
    }
    if(Ran.x<=10||Ran.x>=70||Ran.y<=10||Ran.y>=30||check!=0)
    {
            system("cls");
            printf("GameOver");
            printf("\n Diem Ban Dat Duoc La : %d",ChieuDai-5);            
            exit(0);        
    }
}
void ConMoi()
{
    if(Ran.x==conmoi.x&&Ran.y==conmoi.y)
    {
        ChieuDai++;            
        srand(time(0));
        conmoi.x=rand()%70;
        if(conmoi.x<=10)
            conmoi.x+=11;
        conmoi.y=rand()%30;
        if(conmoi.y<=10)
            conmoi.y+=11;
    }
    else if(conmoi.x==0)
    {
        conmoi.x=rand()%70;
        if(conmoi.x<=10)
           conmoi.x+=11;
        conmoi.y=rand()%30;
        if(conmoi.y<=10)
           conmoi.y+=11;
    }
}
void Left()
{
    int i;
    for(i=0; i<=(xoay[xoay_0].x-Ran.x)&&Dai<ChieuDai; i++)
    {
        gotoxy((Ran.x+i),Ran.y);
        {
            if(Dai==0)
                printf("%c",2);
            else
                printf("%c",5);
        }
        Than[Dai].x=Ran.x+i;
        Than[Dai].y=Ran.y;
        Dai++;
    }
    Xoay();
    if(!kbhit())
        Ran.x--;

}
void Right()
{
    int i;
    for(i=0; i<=(Ran.x-xoay[xoay_0].x)&&Dai<ChieuDai; i++)
    {
        Than[Dai].x=Ran.x-i;
        Than[Dai].y=Ran.y;
        gotoxy(Than[Dai].x,Than[Dai].y);
        {
            if(Dai==0)
                printf("%c",2);
            else
                printf("%c",5);
        }
        
        Dai++;
    }
    Xoay();
    if(!kbhit())
        Ran.x++;
}
void Xoay()
{
    int i,j,diff;
    for(i=xoay_0; i>=0&&Dai<ChieuDai; i--)
    {
        if(xoay[i].x==xoay[i-1].x)
        {
            diff=xoay[i].y-xoay[i-1].y;
            if(diff<0)
                for(j=1; j<=(-diff); j++)
                {
                    Than[Dai].x=xoay[i].x;
                    Than[Dai].y=xoay[i].y+j;
                    gotoxy(Than[Dai].x,Than[Dai].y);
                    printf("%c",5);
                    Dai++;
                    if(Dai==ChieuDai)
                        break;
                }
            else if(diff>0)
                for(j=1; j<=diff; j++)
                {
                    Than[Dai].x=xoay[i].x;
                    Than[Dai].y=xoay[i].y-j;
                    gotoxy(Than[Dai].x,Than[Dai].y);
                    printf("%c",5);
                    Dai++;
                    if(Dai==ChieuDai)
                        break;
                }
        }
        else if(xoay[i].y==xoay[i-1].y)
        {
            diff=xoay[i].x-xoay[i-1].x;
            if(diff<0)
                for(j=1; j<=(-diff)&&Dai<ChieuDai; j++)
                {
                    Than[Dai].x=xoay[i].x+j;
                    Than[Dai].y=xoay[i].y;
                    gotoxy(Than[Dai].x,Than[Dai].y);
                    printf("%c",5);
                    Dai++;
                    if(Dai==ChieuDai)
                        break;
                }
            else if(diff>0)
                for(j=1; j<=diff&&Dai<ChieuDai; j++)
                {
                    Than[Dai].x=xoay[i].x-j;
                    Than[Dai].y=xoay[i].y;
                    gotoxy(Than[Dai].x,Than[Dai].y);
                    printf("%c",5);
                    Dai++;
                    if(Dai==ChieuDai)
                        break;
                }
        }
    }
}
void TaoMap()
{
    system("cls");
    int i;
    gotoxy(conmoi.x,conmoi.y); 
    printf("o");
    for(i=10; i<71; i++)
    {
        gotoxy(i,10);
        printf("%c",176);
        gotoxy(i,30);
        printf("%c",176);
    }
    for(i=10; i<31; i++)
    {
        gotoxy(10,i);
        printf("%c",176);
        gotoxy(70,i);
        printf("%c",176);
    }
}
void KhoiTao()
{
    gotoxy(10,12);
    printf("\n WellCome To UIT Snake Game");
    getch();
    system("cls");
    printf("\tCach Choi \n");
    printf("\nDung cac phim sau de di chuyen %c%c%c%c",25,26,27,28 );
    printf("\n Nhan ESC de thoat");
    printf("\n\nPress any key to play game...");
     getch();
    if(getch()==27)
        exit(0);
}      
void Up()
{
    int i;
    for(i=0; i<=(xoay[xoay_0].y-Ran.y)&&Dai<ChieuDai; i++)
    {
        gotoxy(Ran.x,Ran.y+i);
        {
            if(Dai==0)
                printf("%c",2);
            else
                printf("%c",5);
        }
        Than[Dai].x=Ran.x;
        Than[Dai].y=Ran.y+i;
        Dai++;
    }
    Xoay();
    if(!kbhit())
        Ran.y--;
}
void Delay(int k)
{
    
    int i;
    for(i=0; i<=(100000000); i++);
}
